Skip to content

feat: distribute complypack as multi-platform plugin with container MCP server#31

Open
jpower432 wants to merge 13 commits into
complytime:mainfrom
jpower432:feat/plugin-distribution
Open

feat: distribute complypack as multi-platform plugin with container MCP server#31
jpower432 wants to merge 13 commits into
complytime:mainfrom
jpower432:feat/plugin-distribution

Conversation

@jpower432

@jpower432 jpower432 commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

  • Add --source and --schema repeatable CLI flags to mcp serve so the MCP server can be fully configured without a YAML file (ADR 013)
  • Package the MCP server as a multi-arch container image on GHCR using UBI 9 micro base (ADR 012)
  • Add plugin manifests for Claude Code, Cursor, and Gemini CLI following the superpowers multi-manifest pattern
  • Add CI workflow using org-infra reusable workflows for GHCR publish with SLSA provenance, SBOM, and Sigstore signing
  • Fix CUE definition fragment parsing (cue://module@v0#Definition syntax)
  • Relax ValidateForMCP to not require pack/scan-only fields

Flags syntax

complypack mcp serve \
  --source oci://registry.example.com/gemara/controls:v1 \
  --source oci+http://localhost:5001/gemara/guidance:v1 \
  --schema ci=cue://cue.dev/x/githubactions@v0#Workflow \
  --schema kubernetes

Container invocation

{
  "mcpServers": {
    "complypack": {
      "command": "docker",
      "args": ["run", "--rm", "-i",
               "ghcr.io/complytime/complypack:latest",
               "mcp", "serve",
               "--source", "oci://registry.example.com/gemara/controls:v1",
               "--schema", "ci"]
    }
  }
}

Dependencies

Test plan

  • All existing tests pass (go test -race ./...)
  • Container builds with podman build -f Containerfile
  • MCP server starts from container with flags only (no config file)
  • MCP server starts from container with config file via volume mount
  • CUE registry schemas load correctly (cue://...@v0#Definition syntax)
  • Plugin validates with claude plugin validate .
  • Multi-arch image builds in CI (amd64 + arm64)

@jpower432 jpower432 marked this pull request as draft June 9, 2026 01:49
@jpower432

Copy link
Copy Markdown
Member Author

@beatrizmcouto Pretty much done with any clean up items. This is the first PR where I think review is really important. Will clean it up and see who I can tag.

@jpower432 jpower432 force-pushed the feat/plugin-distribution branch from 38a989b to 5518373 Compare June 9, 2026 23:38
Comment thread .github/workflows/container.yml Fixed
Comment thread .github/workflows/container.yml Fixed
jpower432 added 7 commits June 9, 2026 19:40
Add repeatable --source and --schema flags to the mcp serve command,
allowing direct configuration without a YAML file. When --source flags
are present, a ComplyPackConfig is built from flag values; otherwise
the existing --config file path is used.

- parseSourceFlags: handles oci:// (TLS) and oci+http:// (plain HTTP)
- parseSchemaFlags: handles bare platform names and platform=source syntax
- Refactor NewServer to accept ServerOptions.Config directly

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
Remove hardcoded version "1.0" from buildConfigFromFlags in mcp.go
since the MCP server does not use the version field (it's only needed
for pack/scan commands).

Add comprehensive test for buildConfigFromFlags to verify complete
flag-to-config transformation including source parsing, schema parsing,
and proper struct field population.

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
Multi-stage build with UBI 9 micro base image.
Produces a minimal container for MCP server distribution via GHCR.

Refs: complytime#24
ADR: docs/adr/012-container-mcp-distribution.md

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
Uses org-infra reusable workflows for GHCR publish with SLSA
provenance, SBOM attestations, and Sigstore signing.
Multi-arch (amd64/arm64) build on version tags and main pushes.

Refs: complytime#24

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
Claude Code, Cursor, and Gemini CLI manifests following the
superpowers multi-manifest pattern. Updates .mcp.json to reference
the container image. Restructures skill directory layout.
Removes openpackage.yml and legacy install docs.

Refs: complytime#24

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
Covers Claude Code, OpenCode, flag syntax, config file fallback,
and image verification.

Refs: complytime#24

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
Copy CA certificates into the UBI micro container so the CUE registry
(registry.cue.works) is reachable over TLS.

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
@jpower432 jpower432 force-pushed the feat/plugin-distribution branch from 5518373 to 2378fea Compare June 9, 2026 23:41
Pin reusable workflow references to SHA and pin ubi9-micro to a
versioned digest to satisfy zizmor and hadolint.

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
Comment thread .claude-plugin/plugin.json Outdated
Comment thread .claude-plugin/plugin.json Outdated
Comment thread .cursor-plugin/plugin.json Outdated
Comment thread .cursor-plugin/plugin.json Outdated
Comment thread gemini-extension.json Outdated
Signed-off-by: Jennifer Power <[email protected]>

Co-authored-by: Jennifer Power <[email protected]>
@jpower432 jpower432 requested a review from hbraswelrh June 12, 2026 12:21
Previously, passing only --schema without --source fell through to
config file loading and failed. Now either flag triggers the flags-based
config path.

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
Prevents auto-loading a broken config with placeholder values and
:latest tag. Users copy and fill in their own registry, source, and
pinned version.

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
@jpower432 jpower432 marked this pull request as ready for review June 12, 2026 17:45
@jpower432 jpower432 requested a review from a team as a code owner June 12, 2026 17:45
@jpower432 jpower432 requested review from trevor-vaughan and removed request for a team June 12, 2026 17:45
@hbraswelrh

Copy link
Copy Markdown
Member

@jpower432 Started taking a look. I'll finish up my review first thing Monday.

@trevor-vaughan trevor-vaughan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest running megalinter against the changes.

If you want a light(ish) way to do it locally, I have a project at https://github.com/trevor-vaughan/megalint-config.

Comment thread .github/workflows/container.yml Outdated
Comment thread .github/workflows/container.yml Outdated
Comment thread Containerfile
- Fix allowed_identity_regex to match org-infra reusable workflow origin
- Add Trivy image scan stage between build and sign
- Gate signing on scan success via verify_vuln
- Run container as non-root user (ARG USER_UID=10001)

Assisted-by: Claude (Anthropic, Claude Opus 4.6)
Signed-off-by: Jennifer Power <[email protected]>
@jpower432

Copy link
Copy Markdown
Member Author

I would suggest running megalinter against the changes.

If you want a light(ish) way to do it locally, I have a project at https://github.com/trevor-vaughan/megalint-config.

Thanks @trevor-vaughan. It is running in CI under CI/Standardized CI/Run linters. Are you suggesting a change in that config?

@jpower432 jpower432 requested a review from trevor-vaughan June 12, 2026 22:50

@hbraswelrh hbraswelrh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jpower432 LGTM. One thing I noticed is the incremental editing of the .mcp.json after each task. This requires re-connecting to the complypack mcp server every time. I tried a couple different tests where I intentionally had incorrect mapping-references and it failed to restart the mcp server. I think this is a great move to enforce "correctness" from the start. I like the gitleaks feature, too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Distribute complypack skill and MCP server as a multi-platform plugin

4 participants